#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <cstdlib>
#include <errno.h>
#include <cstring>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
using namespace std;

#define NUM 5

// void *threadsun(void *name)
// {
//     char *str = (char*)name;
//     int cnt=3;
//     while (cnt--)
//     {
//         sleep(1);
//         cout << str << endl;
//     }

//     delete[] str;
//     pthread_exit((void*)"exit");
// }

// int main()
// {
//     pthread_t thread[NUM];

//     for (int i = 1; i <= NUM; i++)
//     {
//         char* buffer= new char[64];//new 动态初始化
//         snprintf(buffer,64,"我是thread-%d号", i);//sizeof的用法
//         pthread_create(&thread[i-1], nullptr, threadsun, buffer);
//     }

//     // int cnt=4;
//     // while (cnt--)
//     // {
//     //     sleep(1);
//     //     cout << "我是主线程，我最牛逼" << endl;
//     // }

//     for (int i = 1; i <= NUM; i++)
//     {
//         // pthread_cancel(thread[i-1]);
        
//         void* ret;
//         int n=pthread_join(thread[i-1],&ret);
//         // if(n==-1) printf("我错了\n");
//         cout<<(int64_t)ret<<strerror(n)<<endl;
//         // cout<<"线程thread"<<i<<"退出了 TID"<<thread[i-1]<<(char*)ret<<strerror(n)<<endl;
//     }

//     pthread_exit(0);  
// }
//主线程return 会使所有的线程都退出，detach是不关心线程的退出值，




// class Request
// {
// public:
//     Request(int start,int end,const string& name)
//     :_start(start)
//     ,_end(end)
//     ,threadname(name)
//     {}
// public:
//     int _start;
//     int _end;
//     string threadname;
// };

// class Response
// {
// public:
//     Response(int result,int exitcode)
//     :_result(result)
//     ,_exitcode(exitcode)
//     {}
// public:
//     int _result;
//     int _exitcode;
// };

// void* sumCount(void*args)
// {
//     Request* rq=static_cast<Request*>(args);
    
//     Response* rep=new Response(0,0);

//     for(int i=rq->_start;i<=rq->_end;i++)
//     {
//         rep->_result+=i;
//     }
//     sleep(5);
//     return rep;
// }

// int main()
// {
//     pthread_t tid;
//     Request* rs=new Request(1,100,"thread 1");
//     pthread_create(&tid,nullptr,sumCount,rs);
    
//     sleep(3);
//     pthread_cancel(tid);
//     void *ret;
//     pthread_join(tid,&ret);
//     // cout<<(int64_t)ret<<endl;
//     // Response* rsp=static_cast<Response*>(ret);
//     // cout<<"thread return"<<tid<<rsp->_result<<pthread_self()<<endl;
//     return 0;
// }
// #include <iostream>
// #include <pthread.h>
// #include <unistd.h>
// #include <errno.h>
// #include <cstring>

// using namespace std;

// void* thread_func(void* arg)
// {
//     cout << "Thread started!" << endl;
//     sleep(2); 
//     cout << "Thread finished!" << endl;
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;

//     pthread_create(&tid, nullptr, thread_func, nullptr);

//     pthread_detach(tid);
//     cout << "Thread detached!" << endl;

//     void* ret;
//     int res = pthread_join(tid, &ret);
//     if (res != 0)
//     {
//         cout << "pthread_join failed. Reason: " << strerror(res) << endl;
//     }

//     return 0;
// }

pthread_mutex_t mxt=PTHREAD_MUTEX_INITIALIZER;


int tickets=1000;

class threadData
{
public:
    threadData(int i)
    {
        threadname="thread -"+to_string(i);
    }
    string threadname;
};

void* getticket(void* args)
{
    threadData *data=static_cast<threadData*>(args);
    const char*name=data->threadname.c_str();
    while(1)
    {
        pthread_mutex_lock(&mxt);
        if(tickets>0)
        {
            usleep(1000);
            tickets--;
            printf("%s,获得一张票，还剩%d\n",name,tickets);
        pthread_mutex_unlock(&mxt);
        }
        else
        {
        pthread_mutex_unlock(&mxt);
            break;
        }
    }

    printf("quit %s",name);

    pthread_exit(nullptr);
}

int main()
{
    vector<pthread_t> tids;
    vector<threadData *> data;

    for(int i=1;i<=NUM;i++)
    {
        pthread_t p;
        threadData* t=new threadData(i);
        pthread_create(&p,nullptr,getticket,t);
        data.push_back(t);
        tids.push_back(p);
    } 

    for(auto i:tids)
    {
        pthread_join(i,nullptr);
    }

    for(auto i:data)
    {
        delete i;
    }

    return 0;
}